# @Time : 2020/6/25 16:34
# @Author : Fioman 
# @Phone : 13149920693
"""
函数式变成中,经常需要把算术运算符当作函数使用.例如,不使用递归计算阶乘.求和可以使用sum函数,但是求积则没有这样的函数.
我们可以使用reduce函数,但是需要一个函数计算序列中两个元素之积.
"""
from functools import reduce
from operator import mul


def fact(n):
    return reduce(lambda a, b: a * b, range(1, n + 1))


# 使用递归
def fact2(n):
    return 1 if n < 2 else n * fact2(n - 1)


# 使用operator模块
def fact3(n):
    return reduce(mul, range(1, n + 1))


"""
operator模块中有一个类函数,能替代从序列中取出元素或读取对象属性的lambda表达式;因此,itemgetter和attrgetter其实会自行构建函数.
根据元组的某个字段给元组列表排序.
itemgetter(1)的作用与lambda fields:fields[1]是一样的:创建一个接收集合的函数,然后返回索引是1的元素.
"""

metro_data = [('Tokyo', 'JP', 36.933, (35.689722, 139.691667)),
              ('Delhi NCR', 'IN', 21.935, (28.613889, 77.208889)),
              ('Mexico City', 'MX', 20.142, (19.433333, -99.133333)),
              ('New York-Newark', 'US', 20.104, (40.808611, -74.020386)),
              ('Sao Paulo', 'BR', 19.649, (-23.547778, -46.635833))]
from operator import itemgetter
for city in sorted(metro_data,key=itemgetter(1)):
    print(city)

# 如果将多个参数传递给itemgetter,它构建的函数会返回提取的值构成的元组.
cc_name = itemgetter(1,0)
print(cc_name)
for city in metro_data:
    print(cc_name(city))

if __name__ == '__main__':
    res1 = fact(10)
    print("res1 = {}".format(res1))
    res2 = fact2(10)
    print("res2 = {}".format(res2))
    res3 = fact3(10)
    print("res3 = {}".format(res3))
